Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


nomadnet/Node.py d661ba053183dfd1c9d3350bc2a8a7d1a70a2ecf (d661ba05) Text, 11.08 KB

Tff7b72import T7ee787os
Tff7b72import T7ee787sys

Tff7b72import T7ee787RNS
Tff7b72import T7ee787time
Tff7b72import T7ee787threading
Tff7b72import T7ee787subprocess
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787umsgpack Tff7b72as T7ee787msgpack

Tff7b72class T56d364NodeTb4b4b4:
Te6edf3JOB_INTERVAL Tff7b72= T79c0ff5
Te6edf3START_ANNOUNCE_DELAY Tff7b72= T79c0ff6

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNomad Network Node starting...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffidentity
Tff7b72selfTff7b72.Td2a8ffdestination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Ta5d6ff"Ta5d6ffnomadnetworkTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnodeTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_file_refresh Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_page_refresh Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounce_interval Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffnode_announce_interval
Tff7b72selfTff7b72.Td2a8ffpage_refresh_interval Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpage_refresh_interval
Tff7b72selfTff7b72.Td2a8fffile_refresh_interval Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fffile_refresh_interval
Tff7b72selfTff7b72.Td2a8ffjob_interval Tff7b72= Te6edf3NodeTff7b72.Td2a8ffJOB_INTERVAL
Tff7b72selfTff7b72.Td2a8ffshould_run_jobs Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffapp_data Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffnode_name

Tff7b72selfTff7b72.Td2a8ffregister_pagesTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffregister_filesTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_connectedTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffname Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpeer_settingsTb4b4b4[Ta5d6ff"Ta5d6ffdisplay_nameTa5d6ff"Tb4b4b4]Tff7b72+Ta5d6ff"Ta5d6ff'Ta5d6ffs NodeTa5d6ff"

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNode Tffea00\"Ta5d6ff"Tff7b72+Tff7b72selfTff7b72.Td2a8ffnameTff7b72+Ta5d6ff"Tffea00\"Ta5d6ff ready for incoming connections on Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffnode_announce_at_startTb4b4b4:
Tff7b72def Td2a8ffdelayed_announceTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Te6edf3NodeTff7b72.Td2a8ffSTART_ANNOUNCE_DELAYTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)

Te6edf3da_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3delayed_announceTb4b4b4)
Te6edf3da_threadTff7b72.Td2a8ffsetDaemonTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3da_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Te6edf3job_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff__jobsTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffsetDaemonTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffregister_pagesTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# TODO: Deregister previously registered pages
T8b949e# that no longer exist.
Tff7b72selfTff7b72.Td2a8ffservedpages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffscan_pagesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpagespathTb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpagespathTff7b72+Ta5d6ff"Ta5d6ffindex.muTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffservedpagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(
Ta5d6ff"Ta5d6ff/page/index.muTa5d6ff"Tb4b4b4,
Te6edf3response_generator Tff7b72= Tff7b72selfTff7b72.Td2a8ffserve_default_indexTb4b4b4,
Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4)

Tff7b72for Te6edf3page Tff7b72in Tff7b72selfTff7b72.Td2a8ffservedpagesTb4b4b4:
Te6edf3request_path Tff7b72= Ta5d6ff"Ta5d6ff/pageTa5d6ff"Tff7b72+Te6edf3pageTff7b72.Td2a8ffreplaceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpagespathTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(
Te6edf3request_pathTb4b4b4,
Te6edf3response_generator Tff7b72= Tff7b72selfTff7b72.Td2a8ffserve_pageTb4b4b4,
Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4)

Tff7b72def Td2a8ffregister_filesTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# TODO: Deregister previously registered files
T8b949e# that no longer exist.
Tff7b72selfTff7b72.Td2a8ffservedfiles Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffscan_filesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fffilespathTb4b4b4)

Tff7b72for Te6edf3file Tff7b72in Tff7b72selfTff7b72.Td2a8ffservedfilesTb4b4b4:
Te6edf3request_path Tff7b72= Ta5d6ff"Ta5d6ff/fileTa5d6ff"Tff7b72+Te6edf3fileTff7b72.Td2a8ffreplaceTb4b4b4(Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fffilespathTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(
Te6edf3request_pathTb4b4b4,
Te6edf3response_generator Tff7b72= Tff7b72selfTff7b72.Td2a8ffserve_fileTb4b4b4,
Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4,
Te6edf3auto_compress Tff7b72= T79c0ff32_000_000Tb4b4b4)

Tff7b72def Td2a8ffscan_pagesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3base_pathTb4b4b4)Tb4b4b4:
Te6edf3files Tff7b72= Tb4b4b4[Te6edf3file Tff7b72for Te6edf3file Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3base_pathTb4b4b4) Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3base_pathTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4) Tff7b72and Te6edf3fileTb4b4b4[Tb4b4b4:T79c0ff1Tb4b4b4] Tff7b72!= Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4]
Te6edf3directories Tff7b72= Tb4b4b4[Te6edf3file Tff7b72for Te6edf3file Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3base_pathTb4b4b4) Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3base_pathTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4) Tff7b72and Te6edf3fileTb4b4b4[Tb4b4b4:T79c0ff1Tb4b4b4] Tff7b72!= Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4]

Tff7b72for Te6edf3file Tff7b72in Te6edf3filesTb4b4b4:
Tff7b72if Tff7b72not Te6edf3fileTff7b72.Td2a8ffendswithTb4b4b4(Ta5d6ff"Ta5d6ff.allowedTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffservedpagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3base_pathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3fileTb4b4b4)

Tff7b72for Te6edf3directory Tff7b72in Te6edf3directoriesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffscan_pagesTb4b4b4(Te6edf3base_pathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3directoryTb4b4b4)

Tff7b72def Td2a8ffscan_filesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3base_pathTb4b4b4)Tb4b4b4:
Te6edf3files Tff7b72= Tb4b4b4[Te6edf3file Tff7b72for Te6edf3file Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3base_pathTb4b4b4) Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3base_pathTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4) Tff7b72and Te6edf3fileTb4b4b4[Tb4b4b4:T79c0ff1Tb4b4b4] Tff7b72!= Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4]
Te6edf3directories Tff7b72= Tb4b4b4[Te6edf3file Tff7b72for Te6edf3file Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3base_pathTb4b4b4) Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3base_pathTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4) Tff7b72and Te6edf3fileTb4b4b4[Tb4b4b4:T79c0ff1Tb4b4b4] Tff7b72!= Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4]

Tff7b72for Te6edf3file Tff7b72in Te6edf3filesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffservedfilesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3base_pathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3fileTb4b4b4)

Tff7b72for Te6edf3directory Tff7b72in Te6edf3directoriesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffscan_filesTb4b4b4(Te6edf3base_pathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3directoryTb4b4b4)

Tff7b72def Td2a8ffserve_pageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3link_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPage request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpeer_settingsTb4b4b4[Ta5d6ff"Ta5d6ffserved_page_requestsTa5d6ff"Tb4b4b4] Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffsave_peer_settingsTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not increase served page request countTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3file_path Tff7b72= Te6edf3pathTff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Ta5d6ff/pageTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpagespathTb4b4b4, T79c0ff1Tb4b4b4)

Te6edf3allowed_path Tff7b72= Te6edf3file_pathTff7b72+Ta5d6ff"Ta5d6ff.allowedTa5d6ff"
Te6edf3request_allowed Tff7b72= Tff7b72False

Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3allowed_pathTb4b4b4)Tb4b4b4:
Te6edf3allowed_list Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffaccessTb4b4b4(Te6edf3allowed_pathTb4b4b4, Te6edf3osTff7b72.Td2a8ffX_OKTb4b4b4)Tb4b4b4:
Te6edf3allowed_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Te6edf3allowed_pathTb4b4b4]Tb4b4b4, Te6edf3stdoutTff7b72=Te6edf3subprocessTff7b72.Td2a8ffPIPETb4b4b4)
Te6edf3allowed_input Tff7b72= Te6edf3allowed_resultTff7b72.Td2a8ffstdout

Tff7b72elseTb4b4b4:
Te6edf3fh Tff7b72= Tffa657openTb4b4b4(Te6edf3allowed_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3allowed_input Tff7b72= Te6edf3fhTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3fhTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)

Te6edf3allowed_hash_strs Tff7b72= Te6edf3allowed_inputTff7b72.Td2a8ffsplitlinesTb4b4b4(Tb4b4b4)

Tff7b72for Te6edf3hash_str Tff7b72in Te6edf3allowed_hash_strsTb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3hash_strTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3allowed_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3hash_strTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3allowed_listTff7b72.Td2a8ffappendTb4b4b4(Te6edf3allowed_hashTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not decode RNS Identity hash from: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3hash_strTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while fetching list of allowed identities for request: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3remote_identityTb4b4b4, Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3remote_identityTff7b72.Td2a8ffhash Tff7b72in Te6edf3allowed_listTb4b4b4:
Te6edf3request_allowed Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Te6edf3request_allowed Tff7b72= Tff7b72False
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDenying request, remote identity was not in list of allowed identitiesTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3request_allowed Tff7b72= Tff7b72True

Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3request_allowedTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffServing page: Ta5d6ff"Tff7b72+Te6edf3file_pathTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffplatformutilsTff7b72.Td2a8ffis_windowsTb4b4b4(Tb4b4b4) Tff7b72and Te6edf3osTff7b72.Td2a8ffaccessTb4b4b4(Te6edf3file_pathTb4b4b4, Te6edf3osTff7b72.Td2a8ffX_OKTb4b4b4)Tb4b4b4:
Te6edf3env_map Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Ta5d6ff"Ta5d6ffPATHTa5d6ff" Tff7b72in Te6edf3osTff7b72.Td2a8ffenvironTb4b4b4:
Te6edf3env_mapTb4b4b4[Ta5d6ff"Ta5d6ffPATHTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3osTff7b72.Td2a8ffenvironTb4b4b4[Ta5d6ff"Ta5d6ffPATHTa5d6ff"Tb4b4b4]
Tff7b72if Te6edf3link_id Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3env_mapTb4b4b4[Ta5d6ff"Ta5d6fflink_idTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3link_idTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3remote_identity Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3env_mapTb4b4b4[Ta5d6ff"Ta5d6ffremote_identityTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3remote_identityTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72if Te6edf3data Tff7b72!= Tff7b72None Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3dataTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3e Tff7b72in Te6edf3dataTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3eTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tb4b4b4(Te6edf3eTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6fffield_Ta5d6ff"Tb4b4b4) Tff7b72or Te6edf3eTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ffvar_Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3env_mapTb4b4b4[Te6edf3eTb4b4b4] Tff7b72= Te6edf3dataTb4b4b4[Te6edf3eTb4b4b4]

Te6edf3generated Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Te6edf3file_pathTb4b4b4]Tb4b4b4, Te6edf3stdoutTff7b72=Te6edf3subprocessTff7b72.Td2a8ffPIPETb4b4b4, Te6edf3stderrTff7b72=Te6edf3subprocessTff7b72.Td2a8ffDEVNULLTb4b4b4, Te6edf3envTff7b72=Te6edf3env_mapTb4b4b4)
Tff7b72return Te6edf3generatedTff7b72.Td2a8ffstdout
Tff7b72elseTb4b4b4:
Te6edf3fh Tff7b72= Tffa657openTb4b4b4(Te6edf3file_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3response_data Tff7b72= Te6edf3fhTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3fhTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3response_data
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRequest deniedTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Te6edf3DEFAULT_NOTALLOWEDTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72None

T8b949e# TODO: Improve file handling, this will be slow for large files
Tff7b72def Td2a8ffserve_fileTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffFile request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpeer_settingsTb4b4b4[Ta5d6ff"Ta5d6ffserved_file_requestsTa5d6ff"Tb4b4b4] Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffsave_peer_settingsTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not increase served file request countTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3file_path Tff7b72= Te6edf3pathTff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Ta5d6ff/fileTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fffilespathTb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3file_name Tff7b72= Te6edf3pathTff7b72.Td2a8ffreplaceTb4b4b4(Ta5d6ff"Ta5d6ff/file/Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffServing file: Ta5d6ff"Tff7b72+Te6edf3file_pathTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Tb4b4b4[Tffa657openTb4b4b4(Te6edf3file_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)Tb4b4b4, Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3file_nameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4]

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffserve_default_indexTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffServing default index for request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Te6edf3DEFAULT_INDEXTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffannounceTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp_data Tff7b72= Tff7b72selfTff7b72.Td2a8ffnameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpeer_settingsTb4b4b4[Ta5d6ff"Ta5d6ffnode_last_announceTa5d6ff"Tb4b4b4] Tff7b72= Tff7b72selfTff7b72.Td2a8fflast_announce
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffannounceTb4b4b4(Te6edf3app_dataTff7b72=Tff7b72selfTff7b72.Td2a8ffapp_dataTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffannounce_propagation_nodeTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff__jobsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffshould_run_jobsTb4b4b4:
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3now Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72+ Tff7b72selfTff7b72.Td2a8ffannounce_intervalTff7b72*T79c0ff60Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpage_refresh_interval Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72if Te6edf3now Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_page_refresh Tff7b72+ Tff7b72selfTff7b72.Td2a8ffpage_refresh_intervalTff7b72*T79c0ff60Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffregister_pagesTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_page_refresh Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8fffile_refresh_interval Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72if Te6edf3now Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_file_refresh Tff7b72+ Tff7b72selfTff7b72.Td2a8fffile_refresh_intervalTff7b72*T79c0ff60Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffregister_filesTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_file_refresh Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffjob_intervalTb4b4b4)

Tff7b72def Td2a8ffpeer_connectedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPeer connected to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffpeer_settingsTb4b4b4[Ta5d6ff"Ta5d6ffnode_connectsTa5d6ff"Tb4b4b4] Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffsave_peer_settingsTb4b4b4(Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not increase node connection countTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3linkTff7b72.Td2a8ffset_link_closed_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_disconnectedTb4b4b4)

Tff7b72def Td2a8ffpeer_disconnectedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPeer disconnected from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72pass

Te6edf3DEFAULT_INDEX Tff7b72= Ta5d6ff'''Ta5d6ff>Default Home Page

Ta5d6ffThis node is serving pages, but the home page file (index.mu) was not found in the page storage directory. This is an auto-generated placeholder.

Ta5d6ffIf you are the node operator, you can define your own home page by creating a file named `*index.mu`* in the page storage directory.
Ta5d6ff'''

Te6edf3DEFAULT_NOTALLOWED Tff7b72= Ta5d6ff'''Ta5d6ff>Request Not Allowed

Ta5d6ffYou are not authorised to carry out the request.
Ta5d6ff'''


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────